#include "MessageProcess.h"
#include <qbkernel/include/qb_base.h>
#include <qbprotocol/include/rdProto.h>
#include <qbprotocol/include/SSQBModel.h>
#include <qbprotocol/include/MessageParserTool.h>
#include <core/Utility.h>
#include "qbprotocol/include/ssLoginProto.h"

using namespace qb;
#define Reg_Func(ID) qbBase::getMessageBond()->RegisterDecodeFunc(ID, auth::ExtracFunc)

#define DelPtr(FUNC, TYPE) \
	case FUNC:\
	{\
		TYPE* p = static_cast<TYPE*>(toDel);\
		delete p;\
		return nullptr;\
	}\
	break;


void auth::InitDecodeFuncs()
{
	Reg_Func(E_FID_QB_USER_PERMISSION_REQ);
	Reg_Func(E_FID_QB_CDC_AUTHORITY_REQ);
	Reg_Func(E_FID_QB_CDC_AUTHORITY_REQ_V2);
	Reg_Func(E_FID_QB_CSI_AUTHORITY_REQ);
}

static void* delAck(int func, void* toDel)
{
	switch (func)
	{
		DelPtr(E_FID_QB_USER_PERMISSION_REQ, xQBUserPermissionAck_c);
		DelPtr(E_FID_QB_CDC_AUTHORITY_REQ, xCDCAuthorityOldAck_c);
		DelPtr(E_FID_QB_CDC_AUTHORITY_REQ_V2, xCDCAuthorityAct_c);
		DelPtr(E_FID_QB_CSI_AUTHORITY_REQ, xCSIAuthorityAct_c);
		DelPtr(E_FID_LGN_PRO_LOGIN_INFO_V2, xLoginLgnSvrProAck_t);
		DelPtr(E_FID_LGN_PRO_RE_LOGIN_INFO, xLoginLgnSvrProAck_t);
	default:
		break;
	}
	return toDel;
}
void* auth::ExtracFunc(int func, const ProtoMessage& msg, void* toDel)
{
	if (toDel != nullptr)
		return delAck(func, toDel);

	switch (func)
	{
	case E_FID_QB_USER_PERMISSION_REQ:
	{
		xQBUserPermissionAck_c* ptr = new xQBUserPermissionAck_c();
		FIELDCOPY(ptr->m_UserId, CParserTool::GetString(msg, "UserId"));
		FIELDCOPY(ptr->m_CompanyId, CParserTool::GetString(msg, "CompanyId"));

		ProtoList msglist;
		if (msg.getList("List", msglist)) {
			for (ProtoList::const_iterator it = msglist.begin(); it != msglist.end(); ++it) {
				if (it->Type != ProtoValue::VAR_MAP)
					continue;

				const ProtoMap& msgmap = *it;
				QBUserPermissionItem item;

				FIELDCOPY(item.m_Index, CParserTool::GetString(msgmap, "Index"));
				FIELDCOPY(item.m_Value, CParserTool::GetString(msgmap, "Value"));
				ptr->m_List.push_back(item);
			}
		}
		return ptr;
	}
	break;
	case E_FID_QB_CDC_AUTHORITY_REQ:
	{
		xCDCAuthorityOldAck_c* ptr = new xCDCAuthorityOldAck_c();
		FIELDCOPY(ptr->m_UserId, CParserTool::GetString(msg, "UserId"));
		FIELDCOPY(ptr->m_CompanyId, CParserTool::GetString(msg, "CompanyId"));

		if (!msg.getInt32("Allowed", ptr->m_Allowed))
			ptr->m_Allowed = 0;
		return ptr;
	}
	break;
	case E_FID_QB_CDC_AUTHORITY_REQ_V2:
	{
		xCDCAuthorityAct_c* ptr = new xCDCAuthorityAct_c();
		FIELDCOPY(ptr->m_user.m_UserId, CParserTool::GetString(msg, "UserId"));
		FIELDCOPY(ptr->m_user.m_CompanyId, CParserTool::GetString(msg, "CompanyId"));

		ProtoList sublist;
		char sTemp[8];
		if (msg.getList("List", sublist))
		{
			for (auto it = sublist.begin(); it != sublist.end(); ++it)
			{
				if (it->Type != ProtoValue::VAR_MAP)
					continue;
				const ProtoMap& msgmap = *it;
				xCDCAuthorityUnit unit;
				memset(sTemp, 0, sizeof(sTemp));
				FIELDCOPY(sTemp, CParserTool::GetString(msgmap, "AuthValue"));
				unit.m_AuthValue = atoi(sTemp);
				FIELDCOPY(unit.m_AuthName, CParserTool::GetString(msgmap, "AuthName"));
				FIELDCOPY(unit.m_AuthNameEn, CParserTool::GetString(msgmap, "AuthNameEn"));
				if (unit.m_AuthValue > 0 && unit.m_AuthName[0] != '\0')
				{
					ptr->m_AuthList.push_back(unit);
				}
			}
		}
		return ptr;
	}
	break;
	case E_FID_QB_CSI_AUTHORITY_REQ:
	{
		xCSIAuthorityAct_c* ptr = new xCSIAuthorityAct_c();
		FIELDCOPY(ptr->m_UserId, CParserTool::GetString(msg, "UserId"));
		FIELDCOPY(ptr->m_CompanyId, CParserTool::GetString(msg, "CompanyId"));
		msg.GetInt32("Allowed", ptr->m_Allowed);
		return ptr;
	}
	break;
	case E_FID_LGN_PRO_LOGIN_INFO_V2:
	case E_FID_LGN_PRO_RE_LOGIN_INFO:
	{
		xLoginLgnSvrProAck_t* ptr = new xLoginLgnSvrProAck_t();

		ProtoList submsg_m_List;
		if (msg.GetList("List", submsg_m_List)) //List
		{
			for (ProtoList::const_iterator it = submsg_m_List.begin(); it != submsg_m_List.end(); ++it)
			{
				if (it->Type != ProtoValue::VAR_MAP)
					continue;
				xGWInfo_t inner_Lis;
				memset(&inner_Lis, 0, sizeof(inner_Lis));
				const ProtoMap& msgmap = *it;

				FIELDCOPY(inner_Lis.ip, CParserTool::GetString(msgmap, "ip"));
				FIELDCOPY(inner_Lis.note, CParserTool::GetString(msgmap, "note"));
				msgmap.getInt32("port", (int&)inner_Lis.port);
				msgmap.getInt32("level", (int&)inner_Lis.level);
				ptr->gwlist.push_back(inner_Lis);
			}
		}

		memset(ptr->cookie, 0, sizeof(ptr->cookie));
		FIELDCOPY(ptr->cookie, CParserTool::GetString(msg, "cookie"));

		memset(ptr->userID, 0, sizeof(ptr->userID));
		FIELDCOPY(ptr->userID, CParserTool::GetString(msg, "userID"));

		memset(ptr->username, 0, sizeof(ptr->username));
		FIELDCOPY(ptr->username, CParserTool::GetString(msg, "username"));

		msg.getInt32("securitylevel", ptr->securitylevel);

		memset(ptr->reserve1, 0, sizeof(ptr->reserve1));
		FIELDCOPY(ptr->reserve1, CParserTool::GetString(msg, "reserve1"));

		memset(ptr->lastip, 0, sizeof(ptr->lastip));
		FIELDCOPY(ptr->lastip, CParserTool::GetString(msg, "lastip"));

		memset(ptr->lastdate, 0, sizeof(ptr->lastdate));
		FIELDCOPY(ptr->lastdate, CParserTool::GetString(msg, "lastdate"));

		memset(ptr->lasttime, 0, sizeof(ptr->lasttime));
		FIELDCOPY(ptr->lasttime, CParserTool::GetString(msg, "lasttime"));

		memset(ptr->reserve2, 0, sizeof(ptr->reserve2));
		FIELDCOPY(ptr->reserve2, CParserTool::GetString(msg, "reserve2"));

		memset(ptr->validtime, 0, sizeof(ptr->validtime));
		FIELDCOPY(ptr->validtime, CParserTool::GetString(msg, "validtime"));

		memset(ptr->serverID, 0, sizeof(ptr->serverID));
		FIELDCOPY(ptr->serverID, CParserTool::GetString(msg, "serverID"));

		msg.getInt32("time", ptr->time);
		msg.getInt32("vid", ptr->vid);
		msg.getInt32("utid", ptr->utid);
		msg.getInt32("flag", ptr->flag);
		return ptr;
	}
	break;
	default:
		break;
	}

	return nullptr;
}

